/**
 * <h3>SysUserController</h3>
 * <p>系统用户管理控制器类</p>
 *
 * <h3>功能描述</h3>
 * <p>提供用户管理相关的接口，包括用户信息的CRUD、角色分配、个人信息维护等功能</p>
 * <p>支持多语言（中英文）用户信息维护，实现了基于Spring Security的权限控制</p>
 * <p>包含用户注册、密码重置、状态管理、作品统计等核心功能</p>
 *
 * <h3>元数据</h3>
 * <ul>
 *    <li>作者：郭强</li>
 *    <li>创建日期：2025年05月06日</li>
 * </ul>
 *
 * <h3>其他信息</h3>
 * <ul>
 *    <li>参考链接：<a href="https://spring.io/projects/spring-security">Spring Security文档</a></li>
 *    <li>示例代码：{@code @PreAuthorize("@ss.hasPermi('system:user:list')")} </li>
 * </ul>
 *
 * @apiNote 所有接口都需要进行权限验证，确保安全访问
 * @implSpec 继承自 {@link BaseController}，使用统一的返回格式和异常处理
 * @since 1.0.0
 */
package com.dnndo.web.controller.system;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.dnndo.common.annotation.Log;
import com.dnndo.common.core.controller.BaseController;
import com.dnndo.common.core.domain.AjaxResult;
import com.dnndo.common.core.domain.PageResult;
import com.dnndo.common.core.domain.R;
import com.dnndo.common.core.domain.entity.SysUser;
import com.dnndo.common.core.domain.model.RegisterBodyto;
import com.dnndo.common.enums.BusinessType;
import com.dnndo.common.utils.SecurityUtils;
import com.dnndo.common.utils.bean.BeanDtoVoUtil;
import com.dnndo.system.domain.OpuslistsToUserInfo;
import com.dnndo.system.domain.SysUserRole;
import com.dnndo.system.domain.dto.*;
import com.dnndo.system.domain.vo.SuggestionVO;
import com.dnndo.system.domain.vo.SysUserVO;
import com.dnndo.system.domain.vo.UserInfoVOEN;
import com.dnndo.system.domain.vo.UserInfoVOZH;
import com.dnndo.system.mapper.SchoolMapper;
import com.dnndo.system.mapper.SysUserRoleMapper;
import com.dnndo.system.service.IOpusService;
import com.dnndo.system.service.ISuggestionService;
import com.dnndo.system.service.ISysUserService;
import com.dnndo.system.service.ISchoolService;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.ApiParam;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;


/**
 * 用户信息
 *
 * @author ruoyi
 */
@RestController
@RequestMapping("/system/user")
public class SysUserController extends BaseController {
  private final ISysUserService userService;

  private final SysUserRoleMapper userRoleMapper;
  private final SchoolMapper schoolMapper;
  private final ISchoolService schoolService;

  private final ISuggestionService suggestionService;

  private final IOpusService opusService;
  private final static int SchoolError = -2;
  private static final int PhoneError = -1;
  private static final int Error = 0;
  private static final String NullString = "";

  public SysUserController(ISysUserService userService, SysUserRoleMapper userRoleMapper, SchoolMapper schoolMapper, ISchoolService schoolService, ISuggestionService suggestionService, IOpusService opusService) {
    this.userService = userService;
    this.userRoleMapper = userRoleMapper;
    this.schoolMapper = schoolMapper;
    this.schoolService = schoolService;
    this.suggestionService = suggestionService;
    this.opusService = opusService;
  }

  /**
   * 获取用户列表
   * @param dto 用户查询条件封装对象，包含用户名、手机号等过滤条件
   * @return PageResult<SysUserVO> 分页后的用户信息列表及总记录数
   * @see com.dnndo.system.domain.vo.SysUserVO
   */
  @PreAuthorize("@ss.hasPermi('system:user:list')")
  @GetMapping("/list")
  public PageResult<SysUserVO> list(SysUserDTO dto) {
    startPage();
    List<SysUser> list = userService.selectUserList(dto);
    return PageResult.pageOk(BeanDtoVoUtil.listVo(list, SysUserVO.class), new PageInfo<>(list).getTotal());
  }

  /**
   * 学校管理员进入校园大使管理看到的列表
   * @param dto 用户查询条件封装对象
   * @return PageResult<SysUserVO> 分页的校园大使列表
   * @see com.dnndo.system.domain.vo.SysUserVO
   */
  @GetMapping("/listR")
  public PageResult<SysUserVO> listR(SysUserDTO dto) {
    startPage();
    List<SysUser> list = userService.selectUserList(dto, getUserId());
    return PageResult.pageOk(BeanDtoVoUtil.listVo(list, SysUserVO.class), new PageInfo<>(list).getTotal());
  }

  /**
   * 根据用户编号获取详细信息
   * @param userId 用户唯一标识符
   * @return R<SysUserVO> 包含用户详细信息的响应结果
   * @see com.dnndo.system.domain.vo.SysUserVO
   */
  @PreAuthorize("@ss.hasPermi('system:user:getInfo')")
  @GetMapping("/getInfo")
  public R<SysUserVO> getInfo(@ApiParam(value = "用户ID", required = true) Long userId) {
    SysUser sysUser = userService.selectUserById(userId);
    return R.ok(BeanDtoVoUtil.convert(sysUser, SysUserVO.class));
  }

  /**
   * 新增用户
   * @param dto 前端传入的用户数据传输对象，包含新增字段
   * @return AjaxResult 操作结果返回对象，包含成功或失败状态
   * @see com.dnndo.system.domain.dto.SysUserInsertDTO
   */
  @PreAuthorize("@ss.hasPermi('system:user:add')")
  @Log(title = "用户管理", businessType = BusinessType.INSERT)
  @PostMapping("/add")
  public AjaxResult add(@Validated @RequestBody SysUserInsertDTO dto) {
    // 判断所选学校是否合作，不合作则自动改为合作
    if (dto.getSchoolId() != null) {
      SchoolDTO school = schoolMapper.selectSchoolListById(Long.valueOf(dto.getSchoolId()));
      if (school != null && (school.getCooperateOr() == null || school.getCooperateOr() == 0)) {
        SchoolDTO update = new SchoolDTO();
        update.setSchoolId(Integer.valueOf(dto.getSchoolId()));
        update.setCooperateOr(1);
        schoolService.updateSchoolById(update);
      }
    }
    //根据手机号查询是否有这个用户
    SysUser sysUser = userService.getOne(new LambdaQueryWrapper<SysUser>()
      .eq(SysUser::getPhonenumber, dto.getPhonenumber())
      .eq(SysUser::getDelFlag, 0));
    if (sysUser != null) {
      return error("新增失败,手机号已存在");
    }
    SysUser user = BeanDtoVoUtil.convert(dto, SysUser.class);
    // 查询普通用户角色信息
//        SysRole role = roleService.getOne(new LambdaQueryWrapper<SysRole>()
//                .eq(SysRole::getRoleType, RoleConstants.ROLE_TYPE_COMMON)
//                .eq(SysRole::getStatus, RoleConstants.ROLE_STATUS_NORMAL)
//                .eq(SysRole::getDelFlag, 0)
//                .orderByDesc(SysRole::getCreateTime)
//                .last("limit 1"));
//        //如果没有普通角色，直接返回注册失败
//        if (role == null) {
//            return error("新增失败,请联系系统管理人员");
//        }
    user.setUserName(dto.getPhonenumber());
    user.setCreateBy(getUserId().toString());
    user.setDelFlag("0");
    user.setCreateTime(new Date());
    user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
    // 插入用户信息
    boolean save = userService.save(user);
    if (save) {
      // 插入用户角色
      SysUserRole userRole = new SysUserRole();

      userRole.setUserId(user.getUserId());
      dto.getRoles().forEach(roleId -> {
        userRole.setRoleId(roleId);
        userRole.setUserId(user.getUserId());
        userRoleMapper.insert(userRole);
      });
    }
    return toAjax(save);
  }

  /**
   * 修改用户
   * @param dto 前端传入的用户数据传输对象，包含更新字段
   * @return AjaxResult 操作结果返回对象，包含成功或失败状态
   * @see com.dnndo.system.domain.dto.SysUserUpdateDTO
   */
  @PreAuthorize("@ss.hasPermi('system:user:edit') or @ss.hasPermi('system:userToSc:getInfo')")
  @Log(title = "用户管理", businessType = BusinessType.UPDATE)
  @PostMapping("/edit")
  public AjaxResult edit(@Validated @RequestBody SysUserUpdateDTO dto) {
    //根据手机号和用户id查询用户信息
    long count = userService.count(new LambdaQueryWrapper<SysUser>()
      .eq(SysUser::getPhonenumber, dto.getPhonenumber())
      .ne(SysUser::getUserId, dto.getUserId())
      .eq(SysUser::getDelFlag, 0));
    if (count > 0) {
      return error("修改失败,手机号已存在");
    }
    SysUser sysUser = BeanDtoVoUtil.convert(dto, SysUser.class);
    sysUser.setUpdateBy(getUserId().toString());
    sysUser.setUpdateTime(new Date());
    sysUser.setUserName(dto.getPhonenumber());
    sysUser.setRoleIds(dto.getRoles().toArray(Long[]::new));
    //修改用户角色表
    userService.updateUserRole(sysUser.getUserId(), sysUser.getRoleIds());
    return toAjax(userService.updateById(sysUser));
  }

  /**
   * 删除用户
   * @param userId 要删除的用户唯一标识符
   * @return AjaxResult 操作结果返回对象，包含成功或失败状态
   * @see com.dnndo.system.domain.dto.SysUserDTO
   */
  @PreAuthorize("@ss.hasPermi('system:user:del')")
  @Log(title = "用户管理", businessType = BusinessType.DELETE)
  @GetMapping("/del")
  public AjaxResult del(@ApiParam(value = "用户ID", required = true) Long userId) {
    if (userId.equals(getUserId())) {
      return error("当前用户不能删除");
    }
    return toAjax(userService.deleteUserById(userId));
  }

  /**
   * 重置密码
   * @param dto 包含用户ID和新密码的重置密码对象
   * @return AjaxResult 操作结果返回对象，包含成功或失败状态
   * @see com.dnndo.system.domain.dto.SysUserResetPwdDTO
   */
  @PreAuthorize("@ss.hasPermi('system:user:resetPwd')")
  @Log(title = "用户管理", businessType = BusinessType.UPDATE)
  @PostMapping("/resetPwd")
  public AjaxResult resetPwd(@RequestBody @Validated SysUserResetPwdDTO dto) {
    SysUser sysUser = BeanDtoVoUtil.convert(dto, SysUser.class);
    userService.checkUserAllowed(sysUser);
    userService.checkUserDataScope(sysUser.getUserId());
    sysUser.setPassword(SecurityUtils.encryptPassword(sysUser.getPassword()));
    sysUser.setUpdateBy(getUserId().toString());
    sysUser.setUpdateTime(new Date());
    return toAjax(userService.resetPwd(sysUser));
  }

  /**
   * 状态修改
   * @param dto 包含用户ID和新状态的状态修改对象
   * @return AjaxResult 操作结果返回对象，包含成功或失败状态
   * @see com.dnndo.system.domain.dto.SysUserUpdStatusDTO
   */
  @PreAuthorize("@ss.hasPermi('system:user:changeStatus')")
  @Log(title = "用户管理", businessType = BusinessType.UPDATE)
  @PostMapping("/changeStatus")
  public AjaxResult changeStatus(@RequestBody @Validated SysUserUpdStatusDTO dto) {
    //不允许操作自己的状态
    if (SecurityUtils.getUserId().equals(dto.getUserId())) {
      return error("不允许修改当前用户状态");
    }
    SysUser user = BeanDtoVoUtil.convert(dto, SysUser.class);
    userService.checkUserAllowed(user);
    userService.checkUserDataScope(user.getUserId());
    user.setUpdateBy(getUserId().toString());
    user.setUpdateTime(new Date());
    return toAjax(userService.updateUserStatus(user));
  }

  /**
   * 获取用户信息
   * @param language 语言类型（zh/en）
   * @return R<SysUserVO> 包含用户详细信息的响应结果
   * @see com.dnndo.system.domain.vo.SysUserVO
   */
  @GetMapping("/user_info")
  public R<SysUserVO> user_info(@ApiParam(value = "语言", required = true) String language) {
    if (language == null) {
      return R.fail("请选择语言");
    }
    //获取用户信息
    SysUser sysUser = userService.selectUserById(getUserId());
    SysUserVO convert = BeanDtoVoUtil.convert(sysUser, SysUserVO.class);
    //判断用户是否有作品(是否是设计师)
    OpuslistsToUserInfo opuslistsToUserInfo = new OpuslistsToUserInfo();
    opuslistsToUserInfo.setUserId(getUserId());
    //获取用户所有作品
    List<OpuslistsToUserInfo> OpusLists = opusService.getOpusListsByUserId(opuslistsToUserInfo);
    int countRakingNotNUll=0;
    if (convert==null){
      return R.fail("登陆过期");
    }
    convert.setUserId(getUserId());
    if(!OpusLists.isEmpty()){
      convert.setDesigner(true);
      //计算所有作品的积分，并通过积分计算等级
      double sumgrade = 0.0;
      for (OpuslistsToUserInfo opuslistsToUserInfo1 : OpusLists) {
        //如果排名不是空，计算参加大赛的个数+1
        if (opuslistsToUserInfo1.getRanking() != null){
          countRakingNotNUll++;
          sumgrade += Double.parseDouble(opuslistsToUserInfo1.getGrade());
        }
        if(opuslistsToUserInfo1.getRanking() != null){
          if (Integer.parseInt(opuslistsToUserInfo1.getRanking())<=5 && Integer.parseInt(opuslistsToUserInfo1.getRanking())>=1){
            convert.setAmbassador(true);
          }
        }else{
          convert.setAmbassador(false);
        }

      }

      convert.setPoints(String.valueOf((int) Math.floor(sumgrade)));
      convert.setGrade(String.valueOf((int) Math.floor(sumgrade/100)));
      //计算参加大赛的个数
      convert.setTheme(countRakingNotNUll);
      //统计作品
      convert.setWorks(OpusLists.size());
      //统计获取的认证
    }else{
      convert.setDesigner(false);
      convert.setAmbassador(false);
      convert.setGrade("0");
      convert.setPoints("0");
      convert.setTheme(0);
      convert.setWorks(0);
      //convert.setAmbassadorCertification(0);
    }

    //补充学校信息  通过 用户学校id查询学校信息
    if (sysUser.getSchoolId() != null) {
      SchoolDTO schoolDTO = schoolMapper.selectSchoolListById(Long.valueOf(sysUser.getSchoolId()));
      if (schoolDTO != null){
        convert.setSchoolName(schoolDTO.getSchoolName());
        convert.setSchoolNameEn(schoolDTO.getSchoolNameEn());
        return R.ok(convert);
      }
      return R.ok(convert, "用学校未查询到");
    } else {
      convert.setSchoolName(NullString);
      convert.setSchoolNameEn(NullString);
      return R.ok(convert, "用户未绑定学校");
    }

  }

  /**
   * 修改用户信息 接口
   * @param dto 修改用户信息的数据传输对象
   * @return R<String> 修改结果
   * @see com.dnndo.system.domain.dto.SysUserUpdataMySelfDTO
   */
  @PutMapping("/update/user_info")
  public R<String> updata_user_info(@Validated SysUserUpdataMySelfDTO dto) {
    dto.setUserId(getUserId());
    System.out.println("updata_user_info:dto = " + dto);
    int row = userService.updateByIdMDTO(dto);
    if (row > 0) {
      return R.ok("更新成功");
    } else {
      if (row == PhoneError) {
        return R.fail("手机号已经被注册");
      }
      if (row == SchoolError) {
        return R.fail("未找到符合的学校");
      }
      return R.fail("更新失败，请稍后重试");
    }

  }

  /**
   * 获取用户自己的投诉建议
   * @param language 语言类型（zh/en）
   * @return R<List<SuggestionVO>> 投诉建议列表
   * @see com.dnndo.system.domain.vo.SuggestionVO
   */
  @GetMapping("/complaint/opinion/list")
  public R<List<SuggestionVO>> updata_user_info(@ApiParam(value = "语言", required = true) String language) {
    if (language == null) {
      return R.fail("请选择语言");
    }
    List<SuggestionDTO> dtoList = suggestionService.selectMySuggestionList(getUserId());
    List<SuggestionVO> voList = BeanDtoVoUtil.listVo(dtoList, SuggestionVO.class);
    return R.ok(voList);
  }

  /**
   * 根据用户id，查询用户信息
   * @param dto 包含用户ID和语言类型的查询对象
   * @return AjaxResult 包含用户信息的响应结果
   * @see com.dnndo.system.domain.vo.UserInfoVOZH
   * @see com.dnndo.system.domain.vo.UserInfoVOEN
   */
  @GetMapping("/getuserInfo")
  public AjaxResult getuserInfo(UserInfoDTO dto) {

    if ("zh".equals(dto.getLanguage())) {
      UserInfoVOZH UserList = userService.selectUserByIdZh(dto.getUserId());
      return AjaxResult.success(UserList);
    }
    if ("en".equals(dto.getLanguage())) {
      UserInfoVOEN UserList = userService.selectUserByIdEn(dto.getUserId());
      return AjaxResult.success(UserList);
    }
    return AjaxResult.error("查询用户信息失败: ");
  }

  /**
   * 用户注册接口
   * @param user 注册用户信息
   * @return R<String> 注册结果
   * @see com.dnndo.common.core.domain.model.RegisterBodyto
   */
  @PostMapping("/register")
  public R<String> register(@RequestBody RegisterBodyto user) {
    return userService.register(user);
  }

/**
 *管理员获取自己的头像，昵称，简介
 */
@GetMapping("/getuserInfoAdmins")
public R<SysUserUpdataMySelfDTO> getuserInfoAdmins() {
  return userService.getuserInfoAdmins(getUserId());
}

  /**
   *管理员修改自己的头像，昵称，简介 http://localhost:9000/system/user/update/user_info_admins
   */
  @PutMapping(path ="/update/user_info_admins", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
  public R<String> updata_user_info_admins(@Validated @RequestPart("dto") SysUserUpdataAdminsDTO dto) {
    dto.setUserId(getUserId());
    int row = userService.updateByIdAdmins(dto);
    if (row > 0){
      return R.ok("更新成功");
    }else {
      return R.fail("更新失败");
    }
  }

}
